1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gdk.Surface; 26 27 private import cairo.Region; 28 private import cairo.Surface : CairoSurface = Surface; 29 private import gdk.CairoContext; 30 private import gdk.Cursor; 31 private import gdk.Device; 32 private import gdk.Display; 33 private import gdk.Event; 34 private import gdk.FrameClock; 35 private import gdk.GLContext; 36 private import gdk.MonitorGdk; 37 private import gdk.VulkanContext; 38 private import gdk.c.functions; 39 public import gdk.c.types; 40 private import glib.ConstructionException; 41 private import glib.ErrorG; 42 private import glib.GException; 43 private import gobject.ObjectG; 44 private import gobject.Signals; 45 private import std.algorithm; 46 47 48 /** 49 * A `GdkSurface` is a rectangular region on the screen. 50 * 51 * It’s a low-level object, used to implement high-level objects 52 * such as [class@Gtk.Window] or [class@Gtk.Dialog] in GTK. 53 * 54 * The surfaces you see in practice are either [iface@Gdk.Toplevel] or 55 * [iface@Gdk.Popup], and those interfaces provide much of the required 56 * API to interact with these surfaces. Other, more specialized surface 57 * types exist, but you will rarely interact with them directly. 58 */ 59 public class Surface : ObjectG 60 { 61 /** the main Gtk struct */ 62 protected GdkSurface* gdkSurface; 63 64 /** Get the main Gtk struct */ 65 public GdkSurface* getSurfaceStruct(bool transferOwnership = false) 66 { 67 if (transferOwnership) 68 ownedRef = false; 69 return gdkSurface; 70 } 71 72 /** the main Gtk struct as a void* */ 73 protected override void* getStruct() 74 { 75 return cast(void*)gdkSurface; 76 } 77 78 /** 79 * Sets our main struct and passes it to the parent class. 80 */ 81 public this (GdkSurface* gdkSurface, bool ownedRef = false) 82 { 83 this.gdkSurface = gdkSurface; 84 super(cast(GObject*)gdkSurface, ownedRef); 85 } 86 87 88 /** */ 89 public static GType getType() 90 { 91 return gdk_surface_get_type(); 92 } 93 94 /** 95 * Create a new popup surface. 96 * 97 * The surface will be attached to @parent and can be positioned 98 * relative to it using [method@Gdk.Popup.present]. 99 * 100 * Params: 101 * parent = the parent surface to attach the surface to 102 * autohide = whether to hide the surface on outside clicks 103 * 104 * Returns: a new `GdkSurface` 105 * 106 * Throws: ConstructionException GTK+ fails to create the object. 107 */ 108 public this(Surface parent, bool autohide) 109 { 110 auto __p = gdk_surface_new_popup((parent is null) ? null : parent.getSurfaceStruct(), autohide); 111 112 if(__p is null) 113 { 114 throw new ConstructionException("null returned by new_popup"); 115 } 116 117 this(cast(GdkSurface*) __p, true); 118 } 119 120 /** 121 * Creates a new toplevel surface. 122 * 123 * Params: 124 * display = the display to create the surface on 125 * 126 * Returns: the new `GdkSurface` 127 * 128 * Throws: ConstructionException GTK+ fails to create the object. 129 */ 130 public this(Display display) 131 { 132 auto __p = gdk_surface_new_toplevel((display is null) ? null : display.getDisplayStruct()); 133 134 if(__p is null) 135 { 136 throw new ConstructionException("null returned by new_toplevel"); 137 } 138 139 this(cast(GdkSurface*) __p, true); 140 } 141 142 /** 143 * Emits a short beep associated to @surface. 144 * 145 * If the display of @surface does not support per-surface beeps, 146 * emits a short beep on the display just as [method@Gdk.Display.beep]. 147 */ 148 public void beep() 149 { 150 gdk_surface_beep(gdkSurface); 151 } 152 153 /** 154 * Creates a new `GdkCairoContext` for rendering on @surface. 155 * 156 * Returns: the newly created `GdkCairoContext` 157 */ 158 public CairoContext createCairoContext() 159 { 160 auto __p = gdk_surface_create_cairo_context(gdkSurface); 161 162 if(__p is null) 163 { 164 return null; 165 } 166 167 return ObjectG.getDObject!(CairoContext)(cast(GdkCairoContext*) __p, true); 168 } 169 170 /** 171 * Creates a new `GdkGLContext` for the `GdkSurface`. 172 * 173 * The context is disconnected from any particular surface or surface. 174 * If the creation of the `GdkGLContext` failed, @error will be set. 175 * Before using the returned `GdkGLContext`, you will need to 176 * call [method@Gdk.GLContext.make_current] or [method@Gdk.GLContext.realize]. 177 * 178 * Returns: the newly created `GdkGLContext` 179 * 180 * Throws: GException on failure. 181 */ 182 public GLContext createGlContext() 183 { 184 GError* err = null; 185 186 auto __p = gdk_surface_create_gl_context(gdkSurface, &err); 187 188 if (err !is null) 189 { 190 throw new GException( new ErrorG(err) ); 191 } 192 193 if(__p is null) 194 { 195 return null; 196 } 197 198 return ObjectG.getDObject!(GLContext)(cast(GdkGLContext*) __p, true); 199 } 200 201 /** 202 * Create a new Cairo surface that is as compatible as possible with the 203 * given @surface. 204 * 205 * For example the new surface will have the same fallback resolution 206 * and font options as @surface. Generally, the new surface will also 207 * use the same backend as @surface, unless that is not possible for 208 * some reason. The type of the returned surface may be examined with 209 * cairo_surface_get_type(). 210 * 211 * Initially the surface contents are all 0 (transparent if contents 212 * have transparency, black otherwise.) 213 * 214 * This function always returns a valid pointer, but it will return a 215 * pointer to a “nil” surface if @other is already in an error state 216 * or any other error occurs. 217 * 218 * Params: 219 * content = the content for the new surface 220 * width = width of the new surface 221 * height = height of the new surface 222 * 223 * Returns: a pointer to the newly allocated surface. The caller 224 * owns the surface and should call cairo_surface_destroy() when done 225 * with it. 226 */ 227 public CairoSurface createSimilarSurface(cairo_content_t content, int width, int height) 228 { 229 auto __p = gdk_surface_create_similar_surface(gdkSurface, content, width, height); 230 231 if(__p is null) 232 { 233 return null; 234 } 235 236 return new CairoSurface(cast(cairo_surface_t*) __p); 237 } 238 239 /** 240 * Creates a new `GdkVulkanContext` for rendering on @surface. 241 * 242 * If the creation of the `GdkVulkanContext` failed, @error will be set. 243 * 244 * Returns: the newly created `GdkVulkanContext`, or 245 * %NULL on error 246 * 247 * Throws: GException on failure. 248 */ 249 public VulkanContext createVulkanContext() 250 { 251 GError* err = null; 252 253 auto __p = gdk_surface_create_vulkan_context(gdkSurface, &err); 254 255 if (err !is null) 256 { 257 throw new GException( new ErrorG(err) ); 258 } 259 260 if(__p is null) 261 { 262 return null; 263 } 264 265 return ObjectG.getDObject!(VulkanContext)(cast(GdkVulkanContext*) __p, true); 266 } 267 268 /** 269 * Destroys the window system resources associated with @surface and 270 * decrements @surface's reference count. 271 * 272 * The window system resources for all children of @surface are also 273 * destroyed, but the children’s reference counts are not decremented. 274 * 275 * Note that a surface will not be destroyed automatically when its 276 * reference count reaches zero. You must call this function yourself 277 * before that happens. 278 */ 279 public void destroy() 280 { 281 gdk_surface_destroy(gdkSurface); 282 } 283 284 /** 285 * Retrieves a `GdkCursor` pointer for the cursor currently set on the 286 * `GdkSurface`. 287 * 288 * If the return value is %NULL then there is no custom cursor set on 289 * the surface, and it is using the cursor for its parent surface. 290 * 291 * Use [method@Gdk.Surface.set_cursor] to unset the cursor of the surface. 292 * 293 * Returns: a `GdkCursor` 294 */ 295 public Cursor getCursor() 296 { 297 auto __p = gdk_surface_get_cursor(gdkSurface); 298 299 if(__p is null) 300 { 301 return null; 302 } 303 304 return ObjectG.getDObject!(Cursor)(cast(GdkCursor*) __p); 305 } 306 307 /** 308 * Retrieves a `GdkCursor` pointer for the @device currently set on the 309 * specified `GdkSurface`. 310 * 311 * If the return value is %NULL then there is no custom cursor set on the 312 * specified surface, and it is using the cursor for its parent surface. 313 * 314 * Use [method@Gdk.Surface.set_cursor] to unset the cursor of the surface. 315 * 316 * Params: 317 * device = a pointer `GdkDevice` 318 * 319 * Returns: a `GdkCursor` 320 */ 321 public Cursor getDeviceCursor(Device device) 322 { 323 auto __p = gdk_surface_get_device_cursor(gdkSurface, (device is null) ? null : device.getDeviceStruct()); 324 325 if(__p is null) 326 { 327 return null; 328 } 329 330 return ObjectG.getDObject!(Cursor)(cast(GdkCursor*) __p); 331 } 332 333 /** 334 * Obtains the current device position and modifier state. 335 * 336 * The position is given in coordinates relative to the upper 337 * left corner of @surface. 338 * 339 * Params: 340 * device = pointer `GdkDevice` to query to 341 * x = return location for the X coordinate of @device 342 * y = return location for the Y coordinate of @device 343 * mask = return location for the modifier mask 344 * 345 * Returns: %TRUE if the device is over the surface 346 */ 347 public bool getDevicePosition(Device device, out double x, out double y, out GdkModifierType mask) 348 { 349 return gdk_surface_get_device_position(gdkSurface, (device is null) ? null : device.getDeviceStruct(), &x, &y, &mask) != 0; 350 } 351 352 /** 353 * Gets the `GdkDisplay` associated with a `GdkSurface`. 354 * 355 * Returns: the `GdkDisplay` associated with @surface 356 */ 357 public Display getDisplay() 358 { 359 auto __p = gdk_surface_get_display(gdkSurface); 360 361 if(__p is null) 362 { 363 return null; 364 } 365 366 return ObjectG.getDObject!(Display)(cast(GdkDisplay*) __p); 367 } 368 369 /** 370 * Gets the frame clock for the surface. 371 * 372 * The frame clock for a surface never changes unless the surface is 373 * reparented to a new toplevel surface. 374 * 375 * Returns: the frame clock 376 */ 377 public FrameClock getFrameClock() 378 { 379 auto __p = gdk_surface_get_frame_clock(gdkSurface); 380 381 if(__p is null) 382 { 383 return null; 384 } 385 386 return ObjectG.getDObject!(FrameClock)(cast(GdkFrameClock*) __p); 387 } 388 389 /** 390 * Returns the height of the given @surface. 391 * 392 * Surface size is reported in ”application pixels”, not 393 * ”device pixels” (see [method@Gdk.Surface.get_scale_factor]). 394 * 395 * Returns: The height of @surface 396 */ 397 public int getHeight() 398 { 399 return gdk_surface_get_height(gdkSurface); 400 } 401 402 /** 403 * Checks whether the surface has been mapped. 404 * 405 * A surface is mapped with [method@Gdk.Toplevel.present] 406 * or [method@Gdk.Popup.present]. 407 * 408 * Returns: %TRUE if the surface is mapped 409 */ 410 public bool getMapped() 411 { 412 return gdk_surface_get_mapped(gdkSurface) != 0; 413 } 414 415 /** 416 * Returns the internal scale factor that maps from surface coordinates 417 * to the actual device pixels. 418 * 419 * On traditional systems this is 1, but on very high density outputs 420 * this can be a higher value (often 2). A higher value means that drawing 421 * is automatically scaled up to a higher resolution, so any code doing 422 * drawing will automatically look nicer. However, if you are supplying 423 * pixel-based data the scale value can be used to determine whether to 424 * use a pixel resource with higher resolution data. 425 * 426 * The scale of a surface may change during runtime. 427 * 428 * Returns: the scale factor 429 */ 430 public int getScaleFactor() 431 { 432 return gdk_surface_get_scale_factor(gdkSurface); 433 } 434 435 /** 436 * Returns the width of the given @surface. 437 * 438 * Surface size is reported in ”application pixels”, not 439 * ”device pixels” (see [method@Gdk.Surface.get_scale_factor]). 440 * 441 * Returns: The width of @surface 442 */ 443 public int getWidth() 444 { 445 return gdk_surface_get_width(gdkSurface); 446 } 447 448 /** 449 * Hide the surface. 450 * 451 * For toplevel surfaces, withdraws them, so they will no longer be 452 * known to the window manager; for all surfaces, unmaps them, so 453 * they won’t be displayed. Normally done automatically as 454 * part of [method@Gtk.Widget.hide]. 455 */ 456 public void hide() 457 { 458 gdk_surface_hide(gdkSurface); 459 } 460 461 /** 462 * Check to see if a surface is destroyed. 463 * 464 * Returns: %TRUE if the surface is destroyed 465 */ 466 public bool isDestroyed() 467 { 468 return gdk_surface_is_destroyed(gdkSurface) != 0; 469 } 470 471 /** 472 * Forces a [signal@Gdk.Surface::render] signal emission for @surface 473 * to be scheduled. 474 * 475 * This function is useful for implementations that track invalid 476 * regions on their own. 477 */ 478 public void queueRender() 479 { 480 gdk_surface_queue_render(gdkSurface); 481 } 482 483 /** 484 * Request a layout phase from the surface's frame clock. 485 * 486 * See [method@Gdk.FrameClock.request_phase]. 487 */ 488 public void requestLayout() 489 { 490 gdk_surface_request_layout(gdkSurface); 491 } 492 493 /** 494 * Sets the default mouse pointer for a `GdkSurface`. 495 * 496 * Passing %NULL for the @cursor argument means that @surface will use 497 * the cursor of its parent surface. Most surfaces should use this default. 498 * Note that @cursor must be for the same display as @surface. 499 * 500 * Use [ctor@Gdk.Cursor.new_from_name] or [ctor@Gdk.Cursor.new_from_texture] 501 * to create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. 502 * 503 * Params: 504 * cursor = a `GdkCursor` 505 */ 506 public void setCursor(Cursor cursor) 507 { 508 gdk_surface_set_cursor(gdkSurface, (cursor is null) ? null : cursor.getCursorStruct()); 509 } 510 511 /** 512 * Sets a specific `GdkCursor` for a given device when it gets inside @surface. 513 * 514 * Passing %NULL for the @cursor argument means that @surface will use the 515 * cursor of its parent surface. Most surfaces should use this default. 516 * 517 * Use [ctor@Gdk.Cursor.new_from_name] or [ctor@Gdk.Cursor.new_from_texture] 518 * to create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. 519 * 520 * Params: 521 * device = a pointer `GdkDevice` 522 * cursor = a `GdkCursor` 523 */ 524 public void setDeviceCursor(Device device, Cursor cursor) 525 { 526 gdk_surface_set_device_cursor(gdkSurface, (device is null) ? null : device.getDeviceStruct(), (cursor is null) ? null : cursor.getCursorStruct()); 527 } 528 529 /** 530 * Apply the region to the surface for the purpose of event 531 * handling. 532 * 533 * Mouse events which happen while the pointer position corresponds 534 * to an unset bit in the mask will be passed on the surface below 535 * @surface. 536 * 537 * An input region is typically used with RGBA surfaces. The alpha 538 * channel of the surface defines which pixels are invisible and 539 * allows for nicely antialiased borders, and the input region 540 * controls where the surface is “clickable”. 541 * 542 * Use [method@Gdk.Display.supports_input_shapes] to find out if 543 * a particular backend supports input regions. 544 * 545 * Params: 546 * region = region of surface to be reactive 547 */ 548 public void setInputRegion(Region region) 549 { 550 gdk_surface_set_input_region(gdkSurface, (region is null) ? null : region.getRegionStruct()); 551 } 552 553 /** 554 * Marks a region of the `GdkSurface` as opaque. 555 * 556 * For optimisation purposes, compositing window managers may 557 * like to not draw obscured regions of surfaces, or turn off blending 558 * during for these regions. With RGB windows with no transparency, 559 * this is just the shape of the window, but with ARGB32 windows, the 560 * compositor does not know what regions of the window are transparent 561 * or not. 562 * 563 * This function only works for toplevel surfaces. 564 * 565 * GTK will update this property automatically if the @surface background 566 * is opaque, as we know where the opaque regions are. If your surface 567 * background is not opaque, please update this property in your 568 * [vfunc@Gtk.Widget.css_changed] handler. 569 * 570 * Params: 571 * region = a region, or %NULL to make the entire 572 * surface opaque 573 */ 574 public void setOpaqueRegion(Region region) 575 { 576 gdk_surface_set_opaque_region(gdkSurface, (region is null) ? null : region.getRegionStruct()); 577 } 578 579 /** 580 * Translates coordinates between two surfaces. 581 * 582 * Note that this only works if @to and @from are popups or 583 * transient-for to the same toplevel (directly or indirectly). 584 * 585 * Params: 586 * to = the target surface 587 * x = coordinates to translate 588 * y = coordinates to translate 589 * 590 * Returns: %TRUE if the coordinates were successfully translated 591 */ 592 public bool translateCoordinates(Surface to, ref double x, ref double y) 593 { 594 return gdk_surface_translate_coordinates(gdkSurface, (to is null) ? null : to.getSurfaceStruct(), &x, &y) != 0; 595 } 596 597 /** 598 * Emitted when @surface starts being present on the monitor. 599 * 600 * Params: 601 * monitor = the monitor 602 */ 603 gulong addOnEnterMonitor(void delegate(MonitorGdk, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 604 { 605 return Signals.connect(this, "enter-monitor", dlg, connectFlags ^ ConnectFlags.SWAPPED); 606 } 607 608 /** 609 * Emitted when GDK receives an input event for @surface. 610 * 611 * Params: 612 * event = an input event 613 * 614 * Returns: %TRUE to indicate that the event has been handled 615 */ 616 gulong addOnEvent(bool delegate(Event, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 617 { 618 return Signals.connect(this, "event", dlg, connectFlags ^ ConnectFlags.SWAPPED); 619 } 620 621 /** 622 * Emitted when the size of @surface is changed, or when relayout should 623 * be performed. 624 * 625 * Surface size is reported in ”application pixels”, not 626 * ”device pixels” (see gdk_surface_get_scale_factor()). 627 * 628 * Params: 629 * width = the current width 630 * height = the current height 631 */ 632 gulong addOnLayout(void delegate(int, int, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 633 { 634 return Signals.connect(this, "layout", dlg, connectFlags ^ ConnectFlags.SWAPPED); 635 } 636 637 /** 638 * Emitted when @surface stops being present on the monitor. 639 * 640 * Params: 641 * monitor = the monitor 642 */ 643 gulong addOnLeaveMonitor(void delegate(MonitorGdk, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 644 { 645 return Signals.connect(this, "leave-monitor", dlg, connectFlags ^ ConnectFlags.SWAPPED); 646 } 647 648 /** 649 * Emitted when part of the surface needs to be redrawn. 650 * 651 * Params: 652 * region = the region that needs to be redrawn 653 * 654 * Returns: %TRUE to indicate that the signal has been handled 655 */ 656 gulong addOnRender(bool delegate(Region, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 657 { 658 return Signals.connect(this, "render", dlg, connectFlags ^ ConnectFlags.SWAPPED); 659 } 660 }